package com.hb.trade.api.push.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.XML;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hb.trade.api.push.task.tenderbulletinphase.TenderBulletinPhase;
import com.hb.trade.api.push.task.tenderprojectphase.TenderProjectPhase;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.lang3.StringUtils;
import org.fzzn.core.util.Enums;
import org.springframework.util.Base64Utils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;

/**
 * describe:
 *
 * @author zhongdl
 * @date 2022/02/21
 */
@Slf4j
public class PushUtil {


    public static String replacePushData(Object pushData, PushTypeEnum pushTypeEnum){
        try {

            ObjectMapper objectMapper = new ObjectMapper();

            objectMapper.setDateFormat(new SimpleDateFormat("yyyyMMddHHmmss"));
            JSONObject contentJSON   = JSONUtil.parseObj(objectMapper.writeValueAsString(pushData),true,true);
            if (Enums.equals(pushTypeEnum,PushTypeEnum.TENDER_PROJECT_PHASE)){

                String xml = "<tenderProjectPhase>" +  XML.toXml(contentJSON) +  "</tenderProjectPhase>";
                xml = StrUtil.replace(xml,"</PROJECT_NAME>","</PROJECT_NAME><INVEST_PROJECT_CODE/>");
                xml = StrUtil.replace(xml,"<ISUNION>O</ISUNION>","<ISUNION>0</ISUNION>");
                xml = StrUtil.replace(xml,"</BID_SECTIONS>","</BID_SECTIONS><ATTACHMENT_SET/>");
                return xml;
            }else if (Enums.equals(pushTypeEnum,PushTypeEnum.TENDER_BULLETIN_PHASE)){
                TenderBulletinPhase tenderBulletinPhase = (TenderBulletinPhase) pushData;
                String noticeContent = tenderBulletinPhase.getNoticeContent().replaceAll("\\&[a-zA-Z]{1,10};", "").
                        replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", "");
                String repalceNoticeContent = PushUtil.getUuid();
                tenderBulletinPhase.setNoticeContent(repalceNoticeContent);
                contentJSON   = JSONUtil.parseObj(objectMapper.writeValueAsString(pushData),true,true);
                String xml = "<tenderBulletinPhase>" +  XML.toXml(contentJSON) +  "</tenderBulletinPhase>";
                xml = StrUtil.replace(xml,repalceNoticeContent,noticeContent);
                xml = StrUtil.replace(xml,"<BULLETIN_DUTY>","<OTHER_CONTENT/><BULLETIN_DUTY>");
                log.info(">>>>>招标公告xml" + xml);
                return xml.replaceAll("[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]", "");

            }else if (Enums.equals(pushTypeEnum,PushTypeEnum.WIN_CANDIDATE_BULLETIN_PHASE)){
                String xml = "<winCandidateBulletinPhase>" +  XML.toXml(contentJSON) +  "</winCandidateBulletinPhase>";
                return xml;

            }else if (Enums.equals(pushTypeEnum,PushTypeEnum.WIN_BID_BULLETIN_PHASE)){
                String xml = "<winBidBulletinPhase>" +  XML.toXml(contentJSON) +  "</winBidBulletinPhase>";
                if (!xml.contains("<UNIONS>")){
                    xml = StrUtil.replace(xml,"<WIN_RESULT>","<UNIONS></UNIONS><WIN_RESULT>");
                }
                return xml;

            }
            return XML.toXml(contentJSON);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getInstanceId() {
        String date = DateUtil.format(new Date(), "yyyyMMdd");
        OrderNumberManager orderNumberManager = SpringUtil.getBean(OrderNumberManager.class);
        Long id = orderNumberManager.getValue(date);
        String value = StringUtils.leftPad(id + "", 7, "0");
        return ConstantUtil.SOURCE_SYSTEM_ID + date + value;
    }
    /**
     * 向前置机推送数据并更新本地log
     *
     * @param url            接口地址
     * @param sourceSystemId 平台编号
     * @param instanceId     交易流水号 //流水号11位平台编码+8位日期+7位自增长整数，共26位
     * @param businessName   业务名称
     * @param xmlContent     请求报文
     * @param userId         请求用户ID
     * @param userName       请求人
     * @throws IOException
     */
    public static JSONObject callService(String url, String sourceSystemId, String instanceId, String businessName, String xmlContent, String userId, String userName) {
        try {
            PostMethod postMethod = new PostMethod(url);
            String soapRequestData = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:rec=\"http://cebpubservice.com/ReceiveService\">\n" +
                    "   <soapenv:Header>\n" +
                    "         <rec:Token>xHyzXcWfhNvo/+sIXhPHgPMtmaarO5p24xhYVLcvgNZIeljXqNYFbkGXfXRG7YwWbg5jVdgOcdo=</rec:Token>\n" +
                    "   </soapenv:Header>\n" +
                    "   <soapenv:Body>\n" +
                    "      <rec:Receive>\n" +
                    "         <rec:SOURCE_SYSTEM_ID>" + sourceSystemId + "</rec:SOURCE_SYSTEM_ID>\n" +
                    "         <rec:TARGET_SYSTEM_ID>" + ConstantUtil.TARGET_SYSTEM_ID_TEST + "</rec:TARGET_SYSTEM_ID>\n" +
                    "         <rec:INSTANCE_ID>" + instanceId + "</rec:INSTANCE_ID>\n" +
                    "         <rec:CA_CODE>1</rec:CA_CODE>\n" +
                    "         <rec:SCHEMA_VERSION>V60.02</rec:SCHEMA_VERSION>\n" +
                    "         <rec:TYPE_FLAG>1</rec:TYPE_FLAG>\n" +
                    "         <rec:DATASET_CODE>" + businessName + "</rec:DATASET_CODE>\n" +
                    "         <rec:XML_CONTENT>" + xmlContent + "</rec:XML_CONTENT>\n" +
                    "         <rec:USER_ID>" + userId + "</rec:USER_ID>\n" +
                    "         <rec:USER_NAME>" + userName + "</rec:USER_NAME>\n" +
                    "         <rec:REQUEST_TIME>" + LocalDateTime.now() + "</rec:REQUEST_TIME>\n" +
                    "      </rec:Receive>\n" +
                    "   </soapenv:Body>\n" +
                    "</soapenv:Envelope>";

            // 然后把Soap请求数据添加到PostMethod中
            byte[] b = soapRequestData.getBytes("utf-8");
            InputStream is = new ByteArrayInputStream(b, 0, b.length);
            RequestEntity re = new InputStreamRequestEntity(is, b.length, "application/soap+xml; charset=utf-8");
            postMethod.setRequestEntity(re);
            // 最后生成一个HttpClient对象，并发出postMethod请求
            HttpClient httpClient = new HttpClient();
            String result = "";
            int statusCode = httpClient.executeMethod(postMethod);
            if (statusCode == 200) {
                result = postMethod.getResponseBodyAsString();
            } else {
                result = postMethod.getResponseBodyAsString();
            }
            JSONObject jsonObject = XML.toJSONObject(result);
            jsonObject = jsonObject.getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ReceiveResponse");
            //成功还是失败
            Boolean serviceFlag = jsonObject.getBool("SERVICE_FLAG");
            //回执信息
            String serviceMessage = jsonObject.getStr("SERVICE_MESSAGE");
            if(!serviceFlag){
                log.error(">>>>>>推送中国服务平台失败，推送信息" + Base64Utils.decodeFromString(xmlContent) + ">>>>>>推送中国服务平台失败回执信息" + serviceMessage);
            }else{
                log.info(">>>>>>回执信息" + serviceMessage);
            }
            return jsonObject;
        } catch (IOException e) {
            return JSONUtil.createObj();
        }
    }

    /**
     *
     * @Description: 获得uuid
     * @Author: zhongdl
     * @Date:2022/2/23 11:22

     **/
    public static String getUuid() {
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        return uuid;
    }
}
